home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc™ Source Code / Messaging / NamRslvr.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  60.4 KB  |  2,082 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        NamRslvr.cpp
  3.  
  4.     Contains:    Implementation of Mac version of ODNameResolver class
  5.  
  6.     Owned by:    Nick Pilch
  7.  
  8.     Copyright:    © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <6>     6/20/96    JP        1323103: Removed an ASSERT & added optional
  13.                                     logging
  14.          <5>     5/24/96    jpa        1246074: SOM_CATCH --> SOM_TRY..SOM_ENDTRY
  15.          <4>    .04.1996    NP        Change ObjectMaster #define for parsing.
  16.          <3>     3/14/96    NP        1290949, 1291292: Fix memory leaks with
  17.                                     whose and every clauses.
  18.          <2>     1/15/96    TJ        Cleaned Up
  19.  
  20.     To Do:
  21.     In Progress:
  22.         
  23. */
  24.  
  25. #ifndef SOM_ODPart_xh
  26. #include "Part.xh"
  27. #endif
  28.  
  29. #ifndef _ODDESUTL_
  30. #include <ODDesUtl.h>
  31. #endif
  32.  
  33. #ifndef _DFLTACS_
  34. #include <DfltAcs.h>
  35. #endif
  36.  
  37. #ifndef SOM_ODDesc_xh
  38. #include "ODDesc.xh"
  39. #endif
  40.  
  41. #ifndef SOM_ODOSLToken_xh
  42. #include "ODOSLTkn.xh"
  43. #endif
  44.  
  45. #ifndef SOM_ODObjectSpec_xh
  46. #include "ODObjSpc.xh"
  47. #endif
  48.  
  49. #ifndef _SEPRIV_
  50. #include "SEPriv.h"
  51. #endif
  52.  
  53. #ifndef _SEUTILS_
  54. #include "SEUtils.h"
  55. #endif
  56.  
  57. #ifndef SOM_ODMessageInterface_xh
  58. #include "MssgIntf.xh"
  59. #endif
  60.  
  61. #ifndef SOM_DefaultAccessorSI_xh
  62. #include "MssgSI.xh"
  63. #endif
  64.  
  65. #ifndef SOM_ODSession_xh
  66. #include "ODSessn.xh"
  67. #endif
  68.  
  69. #ifndef SOM_ODFrame_xh
  70. #include "Frame.xh"
  71. #endif
  72.  
  73. #ifndef SOM_ODPartWrapper_xh
  74. #include "PartWrap.xh"
  75. #endif
  76.  
  77. #ifndef SOM_ODSemanticInterface_xh
  78. #include "SemtIntB.xh"
  79. #endif
  80.  
  81. #ifndef _TEMPSI_
  82. #include "TempSI.h"
  83. #endif
  84.  
  85. #ifndef _OSLTOKEN_
  86. #include "OSLToken.h"
  87. #endif
  88.  
  89. #ifndef _CNTXTOSL_
  90. #include "CntxtOSL.h"
  91. #endif
  92.  
  93. #ifndef _EXCEPT_
  94. #include "Except.h"
  95. #endif
  96.  
  97. #ifndef _OPENHASH_
  98. #include "OpenHash.h"
  99. #endif
  100.  
  101. #ifndef _PLFMDEF_
  102. #include "PlfmDef.h"
  103. #endif
  104.  
  105. #ifndef _SIHLPABS_
  106. #include "SIHlpAbs.h"
  107. #endif
  108.  
  109. #ifndef _ODREGISTRY_
  110. #include "ODRgstry.xh"
  111. #endif
  112.  
  113. #ifndef _DFLTACS_
  114. #include "DfltAcs.h"
  115. #endif
  116.  
  117. #define VARIABLE_MACROS
  118. #define ODNameResolver_Class_Source
  119. #include <NamRslvr.xih>
  120.  
  121. #ifndef SOM_ODExtension_xh
  122. #include <Extensn.xh>
  123. #endif
  124.  
  125. #ifndef _ODDEBUG_
  126. #include "ODDebug.h"
  127. #endif
  128.  
  129. #ifndef _ODMEMORY_
  130. #include "ODMemory.h"
  131. #endif
  132.  
  133. #ifndef _ORDCOLL_
  134. #include "OrdColl.h"
  135. #endif
  136.  
  137. #ifndef SOM_Module_OpenDoc_StandardExtensions_defined
  138. #include "StdExts.xh"
  139. #endif
  140.  
  141. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  142. #include <StdDefs.xh>
  143. #endif
  144.  
  145. #pragma segment ODNameResolver
  146.  
  147. #include "NamRslvB.cpp"    // Platform-independent methods, if any
  148.  
  149. //#undef LOGGING
  150. //#define LOGGING 1
  151.  
  152. //==============================================================================
  153. // Some implementation pointers.
  154. //==============================================================================
  155. /*
  156.  
  157. Format of an ODOSLToken:
  158.  
  159. -descriptorType: typeUserToken
  160.  
  161. -dataHandle is 12 bytes long. The first 8 bytes contain an ODDesc* and
  162. the second 8 bytes contain an embedded OSLContext.
  163.  
  164. */
  165. //==============================================================================
  166. // Constants
  167. //==============================================================================
  168.  
  169. const ODULong kNumPartsExpected = 20; // number of parts expected to be
  170.                                         //    involved in object spec resolution.
  171.  
  172. //==============================================================================
  173. // Function prototypes
  174. //==============================================================================
  175. #define SKIPOMPARSE
  176. #ifdef SKIPOMPARSE
  177. extern "C" { // functions may be called from a .c file
  178. #endif
  179. CallbackCallerProc ReturnCallbackFuncCaller(OSLCallbackSelector whichCallback);
  180.  
  181. ODStatic OSErr CallObjectAccessor(DescType        desiredClass,
  182.                                 const OSLToken*    containerToken,
  183.                                 DescType        containerClass,
  184.                                 DescType        keyForm,
  185.                                 const AEDesc*    keyData,
  186.                                 OSLToken*        value,
  187.                                 Boolean*        procFound,
  188.                                 long            contextRefCon);
  189.                                 
  190. ODStatic OSErr CallCountProc(DescType            desiredClass,
  191.                                 DescType        containerClass,
  192.                                 const OSLToken*    container,
  193.                                 long*            result,
  194.                                 long            contextRefCon);
  195.                                 
  196. ODStatic OSErr CallCompareProc(DescType            oper,
  197.                                 const AEDesc*    obj1,
  198.                                 const AEDesc*    obj2,
  199.                                 ODBoolean*        result,
  200.                                 long            contextRefCon);
  201.                                 
  202. ODStatic OSErr CallDisposeTokenProc(OSLToken*    unneededToken,
  203.                                     long        contextRefCon);
  204.  
  205. ODStatic OSErr CallMarkProc(const OSLToken*    dToken,
  206.                             const OSLToken*    markToken,
  207.                             long            index,
  208.                             long            contextRefCon);
  209.  
  210. ODStatic OSErr CallGetMarkTokenProc(const OSLToken*    dContainerToken,
  211.                                     DescType        containerClass,
  212.                                     OSLToken*        result,
  213.                                     long            contextRefCon);
  214.  
  215. ODStatic OSErr CallAdjustMarksProc(long                newStart,
  216.                                     long            newStop,
  217.                                     const OSLToken*    markToken,
  218.                                     long            contextRefCon);
  219.  
  220. ODStatic OSErr CallGetErrDescProc(AEDesc**    appDescPtr,
  221.                                     long    contextRefCon);
  222.  
  223. ODStatic long GetAppDoesFlags(long contextRefCon);
  224. #ifdef SKIPOMPARSE
  225. }
  226. #endif
  227.  
  228. ODPart* PartFromContext(OSLContext* context);
  229. ODFrame* FrameFromContext(OSLContext* context);
  230. static ODBoolean TokenDefaultCanHandle( Environment* ev,
  231.         ODNameResolver* resolver, ODOSLToken* token );
  232. ODDesc* GetUserODToken(OSLToken* oslToken);
  233. void SetUserODToken(OSLToken* oslToken, ODDesc* odDesc);
  234. static void NewODToken( ODNameResolver* me, ODOSLToken* openDocToken,
  235.                          ODPart* part, ODFrame* frame, OSLToken* newToken);
  236.  
  237. //==============================================================================
  238. // SIContext
  239. //==============================================================================
  240.  
  241. class SIContext
  242. {
  243.   public:
  244.  
  245.     SIContext(Environment* ev, ODPart* part, ODFrame* frame,
  246.                 ODNameResolver* resolver,
  247.                 ODBoolean isDefaultToken = kODFalse);
  248.     ~SIContext();
  249.     
  250.     ODPart*             GetPart() {return fPart;}
  251.     ODFrame*             GetFrame() {return fFrame;}
  252.     ODNameResolver*        GetNameResolver() {return fNameResolver;}
  253.     ODBoolean             IsDefaultToken() {return fIsDefaultToken;}
  254.     void                 SetIsDefaultToken(ODBoolean isDefault)
  255.                                             {fIsDefaultToken = isDefault;}
  256.   private:
  257.     ODPart*            fPart;
  258.     ODFrame*        fFrame;
  259.     ODNameResolver*    fNameResolver;
  260.     ODBoolean        fIsDefaultToken;
  261. };
  262.  
  263. SIContext::SIContext(Environment* ev, ODPart* part, ODFrame* frame ,
  264.                 ODNameResolver* resolver,
  265.                 ODBoolean isDefaultToken)
  266. {
  267.     if (part)
  268.         part->Acquire(ev);
  269.     if (frame)
  270.         frame->Acquire(ev);
  271.     fPart = part;
  272.     fFrame = frame;
  273.     fNameResolver = resolver;
  274.     fIsDefaultToken = isDefaultToken;
  275.     
  276.     LOG("SIContext created part=%8X, frame=%8X\n", fPart, fFrame);
  277.     ASSERT_FRAME_MATCHES_PART( ev, frame, part );
  278. }
  279.  
  280. SIContext::~SIContext()
  281. {
  282.     Environment*    ev = somGetGlobalEnvironment();
  283.  
  284.     LOG("SIContext destroyed part=%8X, frame=%8X\n", fPart, fFrame);
  285.     TRY
  286.         if (fPart)
  287.             fPart->Release(ev);
  288.         if (fFrame)
  289.             fFrame->Release(ev);
  290.     CATCH_ALL
  291.     ENDTRY
  292. }
  293.  
  294. //------------------------------------------------------------------------------
  295. // DeleteAContext
  296. //------------------------------------------------------------------------------
  297.  
  298. inline void DeleteAContext(OSLContext* context)
  299. {
  300.     delete (SIContext*)(context->refCon);
  301. #if ODDebug
  302.     context->refCon = 0x50FF8001;
  303. #endif
  304. //    delete context;
  305. }
  306.  
  307. //------------------------------------------------------------------------------
  308. // PartFromContext
  309. //------------------------------------------------------------------------------
  310.  
  311. ODPart* PartFromContext(OSLContext* context)
  312. {
  313.     ODPart*    part = ((SIContext*)(context->refCon))->GetPart();
  314.     LOG("Part %#8X returned from OSLContext\n", part);
  315.     return part;
  316. }
  317.  
  318. //------------------------------------------------------------------------------
  319. // FrameFromContext
  320. //------------------------------------------------------------------------------
  321.  
  322. ODFrame* FrameFromContext(OSLContext* context)
  323. {
  324.     ODFrame* frame = ((SIContext*)(context->refCon))->GetFrame();
  325.     LOG("Frame %#8X returned from OSLContext\n", frame);
  326.     return frame;
  327. }
  328.  
  329. //------------------------------------------------------------------------------
  330. // SIContextFromOSLToken
  331. //
  332. //    Return pointer to SIContext that is referenced from this OSLToken.
  333. //------------------------------------------------------------------------------
  334.  
  335. static SIContext* SIContextFromOSLToken(ODNameResolver* resolver,
  336.                                         const OSLToken* token)
  337. {
  338.     WASSERT(token->dataHandle != kODNULL);
  339.     OSLContext context;
  340.     OSLGetTokenContext(token, &context);
  341.     return (SIContext*)(context.refCon);
  342. }
  343.  
  344. //------------------------------------------------------------------------------
  345. // SIContextFromToken
  346. //
  347. //    Return pointer to SIContext that is referenced from this ODOSLToken.
  348. //------------------------------------------------------------------------------
  349.  
  350. static SIContext* SIContextFromToken(ODNameResolver* resolver,
  351.                                         ODOSLToken* token)
  352. {
  353.     AEDesc    tokenAsAEDesc;
  354.     SIContext*    retVal;
  355.  
  356.     WASSERT(token != kODNULL);
  357.     THROW_IF_ERROR(ODDescToAEDesc(token, &tokenAsAEDesc));
  358.     WASSERT(tokenAsAEDesc.dataHandle != kODNULL);
  359.     retVal = SIContextFromOSLToken(resolver, &tokenAsAEDesc);
  360.     AEDisposeDesc(&tokenAsAEDesc);
  361.     return retVal;
  362. }
  363.  
  364. //------------------------------------------------------------------------------
  365. // SetIsDefaultToken
  366. //------------------------------------------------------------------------------
  367.  
  368. static void SetIsDefaultToken(ODNameResolver* resolver,
  369.                                 ODOSLToken* token, ODBoolean isDefaultToken)
  370. {
  371.     WASSERT(token != kODNULL);
  372.     SIContext* sic = SIContextFromToken(resolver, token);
  373.     WASSERT(sic != kODNULL);
  374.     sic->SetIsDefaultToken(isDefaultToken);
  375. }
  376.  
  377. //------------------------------------------------------------------------------
  378. // MakeNULLToken
  379. //------------------------------------------------------------------------------
  380.  
  381. inline static void MakeNULLToken( OSLToken *theToken )
  382. {
  383.     theToken->descriptorType = typeNull ;
  384.     theToken->dataHandle = NULL ;
  385. }
  386.     
  387. //==============================================================================
  388. // SIContextTableKey
  389. //==============================================================================
  390.  
  391. struct SIContextTableKey
  392. {
  393.     ODPart*        fPart;
  394.     ODFrame*    fFrame;
  395.     SIContextTableKey(ODPart* part, ODFrame* frame) {fPart = part;
  396.                                                         fFrame = frame;}
  397. };
  398.  
  399. //==============================================================================
  400. // ODNameResolver
  401. //==============================================================================
  402.  
  403. //------------------------------------------------------------------------------
  404. // ODNameResolver::somInit
  405. //------------------------------------------------------------------------------
  406.  
  407. //------------------------------------------------------------------------------
  408. // ODNameResolver::InitNameResolver
  409. //------------------------------------------------------------------------------
  410.  
  411. SOM_Scope void  SOMLINK ODNameResolverInitNameResolver(ODNameResolver *somSelf, Environment *ev,
  412.         ODSession* session)
  413. {
  414.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  415.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverInitNameResolver");
  416.  
  417.     SOM_TRY
  418.  
  419.     /* Moved from somInit. SOM itself sets fields to zero
  420.     _fRootContext.getCallerProc = kODNULL;
  421.     _fRootContext.refCon = 0;
  422.     _fCurrentlyResolving = 0;
  423.     _fSession = kODNULL;
  424.     _fContextTable = kODNULL;
  425.     _fCurrentContextPart = kODNULL;
  426.     _fHashTableRefCount = 0;
  427.     */
  428.     
  429.     somSelf->InitObject(ev);
  430.  
  431.     _fSession = session;
  432.  
  433.     const ODUShort        kODOSLContextSize = sizeof(OSLContext);
  434.     const ODBoolean        kNotInSystemHeap = kODFalse;
  435.     ODFrame* const        kNoFrameInfo = kODNULL;
  436.  
  437.     somSelf->CreateContext(ev, kODAppShell, kNoFrameInfo, &_fRootContext);
  438.     THROW_IF_ERROR(OSLObjectInit(&_fRootContext));
  439.     THROW_IF_NULL(_fContextTable = new OpenHashTable(OpenHashTable::EqualTwoLongs, OpenHashTable::HashTwoLongs) );
  440.     _fContextTable->Initialize(kNumPartsExpected, sizeof(SIContextTableKey),
  441.                                 kODOSLContextSize);
  442.     _fCurrentContextPart = new OrderedCollection;
  443.     somSelf->AddNewContextPartToTopOfStack(ev, (ODPart*)kODAppShell);
  444. //    _fCurrentContextPart = kODAppShell;
  445.     _fErrDescList = new OrderedCollection;
  446.  
  447.     SOM_CATCH_ALL
  448.     SOM_ENDTRY
  449. }
  450.  
  451. //------------------------------------------------------------------------------
  452. // ODNameResolver::somUninit
  453. //------------------------------------------------------------------------------
  454.  
  455. SOM_Scope void  SOMLINK ODNameResolversomUninit(ODNameResolver *somSelf)
  456. {
  457.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  458.     ODNameResolverMethodDebug("ODNameResolver","somUninit");
  459.  
  460.     TRY
  461.         // somSelf->FlushContextCache(somGetGlobalEnvironment());
  462.         // It is incorrect to call methods on somSelf inside somUninit, 
  463.         // a subclass may have already been somUninited.  See OpenDoc Building Code for details.
  464.         // Instead the implementation of FlushContextCache has been copied here.
  465.         
  466.         if (_fContextTable)
  467.         {
  468.             // BEGIN copy of FlushContextCache implementation
  469.             OSLContext                value;
  470.             OpenHashTableIterator   i(_fContextTable);
  471.             
  472.             if (_fHashTableRefCount == 0)
  473.                 for (i.First((void*) 0, &value); i.IsNotComplete(); i.Next((void*) 0, &value))
  474.                 {
  475.                     DeleteAContext(&value);
  476.                     i.RemoveCurrent();
  477.                 }
  478.             // END copy of FlushContextCache implementation
  479.         }
  480.         
  481.     CATCH_ALL
  482.     ENDTRY
  483.         
  484.     DeleteAContext(&_fRootContext);
  485.     ODDeleteObject(_fContextTable);
  486.     ODDeleteObject(_fCurrentContextPart);
  487.     ODDeleteObject(_fErrDescList);
  488. }
  489. #if 0
  490. //------------------------------------------------------------------------------
  491. // ODNameResolver::Purge
  492. //------------------------------------------------------------------------------
  493.  
  494. SOM_Scope ODSize  SOMLINK ODNameResolverPurge(ODNameResolver *somSelf, Environment *ev,
  495.         ODSize size)
  496. {
  497. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  498.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverPurge");
  499.  
  500.     ODUnused(size);
  501.     return 0;
  502. }
  503. #endif /* 0 */
  504. //------------------------------------------------------------------------------
  505. // ODNameResolver::AddErrDescToList
  506. //------------------------------------------------------------------------------
  507.  
  508. struct ErrorDescRec
  509. {
  510.     AEDesc    aeDesc;
  511.     ODDesc*    odDesc;
  512. };
  513.  
  514. SOM_Scope AEDesc*  SOMLINK ODNameResolverAddErrDescToList(ODNameResolver *somSelf, Environment *ev,
  515.         ODDesc* odDesc)
  516. {
  517.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  518.     ODNameResolverMethodDebug("ODNameResolver","AddErrDescToList");
  519.  
  520.     ErrorDescRec*    descRec = new ErrorDescRec;
  521.     descRec->odDesc = odDesc;
  522.     THROW_IF_ERROR(ODDescToAEDesc(odDesc, &descRec->aeDesc));
  523.     _fErrDescList->AddFirst(descRec);
  524.     return &descRec->aeDesc;
  525. }
  526.  
  527. //------------------------------------------------------------------------------
  528. // ODNameResolver::Resolve
  529. //------------------------------------------------------------------------------
  530.  
  531. // FOR CallGetErrDescProc. WE REALLY SHOULD BE KEEPING A LIST OF THESE FOR EVERY
  532. //    PART. OSL WILL WRITE INTO THE DESCRIPTOR IF IT IS A NULL DESCRIPTOR.
  533. //    IF AN APP RETURNS A NON-NULL DESCRIPTOR, THEN THE OSL WILL NOT WRITE INTO
  534. //    IT (ASSUMING THAT IT WAS A PREVIOUSLY WRITTEN-INTO ONE?
  535.  
  536. SOM_Scope void  SOMLINK ODNameResolverResolve(ODNameResolver *somSelf, Environment *ev,
  537.         ODObjectSpec* theObject, ODOSLToken* token, ODPart* contextPart)
  538. {
  539.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  540.     ODNameResolverMethodDebug("ODNameResolver","Resolve");
  541.  
  542.     OSLContext        context;
  543.     OSErr            error;
  544.     ODFrame* const    kNoFrameInfo = kODNULL;
  545.     ODBoolean        contextPartStackChanged = kODFalse;
  546.  
  547.     SOM_TRY
  548.         somSelf->AddNewContextPartToTopOfStack(ev, contextPart);
  549.         contextPartStackChanged = kODTrue;
  550.  
  551.         ODSemanticInterface* theSI = somSelf->AcquireSemtIntf(ev, contextPart);
  552.         if (!theSI)
  553.             THROW(errAENoSuchObject);
  554.         else if (contextPart != kODAppShell)
  555.             theSI->Release(ev);
  556.  
  557.         somSelf->GetContextForPart(ev, contextPart, kNoFrameInfo, &context);
  558.     
  559.         AEDesc objectSpecifier;
  560.         THROW_IF_ERROR( ODDescToAEDesc( theObject, &objectSpecifier ) );
  561.     
  562. #ifdef TESTING_EXMN
  563.         // replace the null desc at the root of containment with 'exmn'
  564.         (void)Munger( objectSpecifier.dataHandle, 0, "null", 4, "exmn", 4 );
  565. #endif
  566.  
  567.         AEDesc realToken = NULL_DESCRIPTOR_DEFINITION;
  568.     
  569.         ++_fCurrentlyResolving;
  570.         error = OSLResolve(&objectSpecifier, &realToken, &context);
  571.         --_fCurrentlyResolving;
  572.     
  573.         AEDisposeDesc(&objectSpecifier);
  574.         if (error == noErr)
  575.             error = AEDescToODDesc( &realToken, token );
  576.         AEDisposeDesc(&realToken);
  577.         
  578.         somSelf->DeleteTopOfContextPartStack(ev);
  579.  
  580.         THROW_IF_ERROR (error);
  581.     SOM_CATCH_ALL
  582.         if (contextPartStackChanged)
  583.             somSelf->DeleteTopOfContextPartStack(ev);
  584.     SOM_ENDTRY
  585.  
  586.     TRY
  587.         OrderedCollectionIterator    iter(_fErrDescList);
  588.         ErrorDescRec*                element;
  589.     
  590.         for (element = (ErrorDescRec*)iter.First();
  591.                 iter.IsNotComplete();
  592.                 element = (ErrorDescRec*)iter.Next())
  593.         {
  594.             AEDescToODDesc(&element->aeDesc, element->odDesc);
  595.             AEDisposeDesc(&element->aeDesc);
  596.         }
  597.         _fErrDescList->DeleteAll();
  598.     CATCH_ALL
  599.         _fErrDescList->DeleteAll();
  600.     ENDTRY
  601. }
  602.  
  603. //------------------------------------------------------------------------------
  604. // ODNameResolver::AcquireSemtIntf
  605. //
  606. //    Convenience function. Returns the SemanticInterface object associated with
  607. //    an ODPart object or kODNULL if none exists.
  608. //------------------------------------------------------------------------------
  609.  
  610. SOM_Scope ODSemanticInterface*  SOMLINK ODNameResolverAcquireSemtIntf(ODNameResolver *somSelf, Environment *ev,
  611.         ODPart* part)
  612. {
  613.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  614.     ODNameResolverMethodDebug("ODNameResolver","AcquireSemtIntf");
  615.  
  616.     ODSemanticInterface*    theSI;
  617.  
  618.     if (part == kODAppShell)
  619.         theSI = _fSession->AcquireShellSemtInterface(ev);
  620.     else
  621.     {
  622.         if (part->HasExtension(ev, kODExtSemanticInterface))
  623.             theSI = (ODSemanticInterface*)part->AcquireExtension(ev, 
  624.                                                         kODExtSemanticInterface);
  625.         else
  626.             theSI = kODNULL;
  627.     }
  628.  
  629.     return theSI;
  630. }
  631.  
  632. //------------------------------------------------------------------------------
  633. // ODNameResolver::GetSession
  634. //
  635. //    Convenience function. Returns the SemanticInterface object associated with
  636. //    an ODPart object or kODNULL if none exists.
  637. //------------------------------------------------------------------------------
  638.  
  639. SOM_Scope ODSession*  SOMLINK ODNameResolverGetSession(ODNameResolver *somSelf, Environment *ev)
  640. {
  641.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  642.     ODNameResolverMethodDebug("ODNameResolver","GetSession");
  643.     
  644.     return _fSession;
  645. }
  646.  
  647. //------------------------------------------------------------------------------
  648. // ODNameResolver::GetPartFromToken
  649. //------------------------------------------------------------------------------
  650.  
  651. SOM_Scope ODPart*  SOMLINK ODNameResolverGetPartFromToken(ODNameResolver *somSelf, Environment *ev,
  652.         OSLToken* token)
  653. {
  654. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  655.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverGetPartFromToken");
  656.  
  657.     OSLContext    context;
  658.     ODPart*        part;
  659.  
  660.     if (OSErr error = OSLGetTokenContext(token, &context))
  661.     {
  662.         part = kODNULL;
  663.         ODSetSOMException(ev, error);
  664.     }
  665.     else
  666.         part = PartFromContext(&context);
  667.     
  668.     ASSERT_FRAME_MATCHES_PART( ev, FrameFromContext(&context), part );
  669.     return part;
  670. }
  671.  
  672. //------------------------------------------------------------------------------
  673. // ODNameResolver::AddNewContextPartToTopOfStack
  674. //------------------------------------------------------------------------------
  675.  
  676. SOM_Scope void  SOMLINK ODNameResolverAddNewContextPartToTopOfStack(ODNameResolver *somSelf, Environment *ev,
  677.         ODPart* contextPart)
  678. {
  679.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  680.     ODNameResolverMethodDebug("ODNameResolver","AddNewContextPartToTopOfStack");
  681.  
  682.     _fCurrentContextPart->AddFirst(contextPart);
  683. }
  684.  
  685. //------------------------------------------------------------------------------
  686. // ODNameResolver::DeleteTopOfContextPartStack
  687. //------------------------------------------------------------------------------
  688.  
  689. SOM_Scope void  SOMLINK ODNameResolverDeleteTopOfContextPartStack(ODNameResolver *somSelf, Environment *ev)
  690. {
  691.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  692.     ODNameResolverMethodDebug("ODNameResolver","DeleteTopOfContextPartStack");
  693.  
  694.     _fCurrentContextPart->RemoveFirst();
  695. }
  696.  
  697. //------------------------------------------------------------------------------
  698. // ODNameResolver::GetCurrentContextPart
  699. //------------------------------------------------------------------------------
  700.  
  701. SOM_Scope ODPart*  SOMLINK ODNameResolverGetCurrentContextPart(ODNameResolver *somSelf, Environment *ev)
  702. {
  703.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  704.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverGetCurrentContextPart");
  705.  
  706.     OSLContext    curContext;
  707.  
  708.     // IF WE'RE IN THE OSL, THE OSL IS DETERMINING THE CONTEXT. OTHERWISE, WE
  709.     //    KEEP THAT STATE.
  710.     if (_fCurrentlyResolving)
  711.     {
  712.         THROW_IF_ERROR(GetCurrentContext(&curContext));
  713.         return PartFromContext(&curContext);
  714.     }
  715.     else
  716. //        return _fCurrentContextPart;
  717.         return (ODPart*)_fCurrentContextPart->First();
  718. }
  719.  
  720. //------------------------------------------------------------------------------
  721. // ODNameResolver::SetCurrentContextPart
  722. //------------------------------------------------------------------------------
  723.  
  724. SOM_Scope void  SOMLINK ODNameResolverSetCurrentContextPart(ODNameResolver *somSelf, Environment *ev,
  725.         ODPart* part)
  726. {
  727.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  728.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverSetCurrentContextPart");
  729.  
  730.     // DON'T ALLOW SETTING INTERNAL OSL STATE.
  731.     ASSERTM(!_fCurrentlyResolving, kODErrUndefined, "ODNameResolver: SetCurrentContextPart: Unexpected State.");
  732.     // $$$$$ NEED TO DO REFCOUNTING HERE
  733.     _fCurrentContextPart->RemoveFirst();
  734.     _fCurrentContextPart->AddFirst(part);
  735. //    _fCurrentContextPart = part;
  736. }
  737.  
  738. //------------------------------------------------------------------------------
  739. // ODNameResolver::GetContextForPart
  740. //------------------------------------------------------------------------------
  741.  
  742. SOM_Scope void  SOMLINK ODNameResolverGetContextForPart(ODNameResolver *somSelf, Environment *ev,
  743.         ODPart* part,
  744.         ODFrame* frame,
  745.         OSLContext* context)
  746. {
  747.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  748.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverGetContextForPart");
  749.  
  750.     SOM_TRY
  751.  
  752.     OSLContext            localContext;
  753.     SIContextTableKey    key(part, frame);
  754.  
  755. //    if (frame)
  756.     ASSERT_FRAME_MATCHES_PART( ev, frame, part );
  757.  
  758.     if (part == kODAppShell)
  759.         *context = _fRootContext;
  760.     else if (_fContextTable->GetValue(&key, context))
  761.         ;
  762.     else
  763.     {
  764.         somSelf->CreateContext(ev, part, frame, &localContext);
  765.         _fContextTable->ReplaceEntry(&key, &localContext);
  766.         *context = localContext;
  767.     }
  768.  
  769.     SOM_CATCH_ALL
  770.     SOM_ENDTRY
  771. }
  772.  
  773. //------------------------------------------------------------------------------
  774. // ODNameResolver::CreateContext
  775. //------------------------------------------------------------------------------
  776.  
  777. SOM_Scope void  SOMLINK ODNameResolverCreateContext(ODNameResolver *somSelf, Environment *ev,
  778.         ODPart* part,
  779.         ODFrame* frame,
  780.         OSLContext* context)
  781. {
  782. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  783.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverCreateContext");
  784.  
  785.     SOM_TRY
  786.  
  787.     SIContext*    siContext;
  788.  
  789.     context->getCallerProc = ReturnCallbackFuncCaller;
  790.  
  791.     ASSERT_FRAME_MATCHES_PART( ev, frame, part );
  792.     siContext = new SIContext(ev, part, frame, somSelf);
  793.  
  794.     context->refCon = (long)siContext;
  795.  
  796.     SOM_CATCH_ALL
  797.     SOM_ENDTRY
  798. }
  799.  
  800. //------------------------------------------------------------------------------
  801. // ODNameResolver::FlushContextCache
  802. //------------------------------------------------------------------------------
  803.  
  804. SOM_Scope void  SOMLINK ODNameResolverFlushContextCache(ODNameResolver *somSelf, Environment *ev)
  805. {
  806.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  807.     ODNameResolverMethodDebug("ODNameResolver","FlushContextCache");
  808.  
  809.     OSLContext                value;
  810.     OpenHashTableIterator   i(_fContextTable);
  811.     
  812.     if (_fHashTableRefCount == 0)
  813.         for (i.First((void*) 0, &value); i.IsNotComplete(); i.Next((void*) 0, &value))
  814.         {
  815.             DeleteAContext(&value);
  816.             i.RemoveCurrent();
  817.         }
  818. }
  819.  
  820. //------------------------------------------------------------------------------
  821. // ODNameResolver::NeedContextCache
  822. //------------------------------------------------------------------------------
  823.  
  824. SOM_Scope void  SOMLINK ODNameResolverNeedContextCache(ODNameResolver *somSelf, Environment *ev,
  825.         ODBoolean lockIt)
  826. {
  827.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  828.     ODNameResolverMethodDebug("ODNameResolver","NeedContextCache");
  829.  
  830.     if (lockIt) {
  831.         WASSERT(_fHashTableRefCount >= 0);
  832.         ++_fHashTableRefCount;
  833.     }
  834.     else {
  835.         --_fHashTableRefCount;
  836.         WASSERT(_fHashTableRefCount >= 0);
  837.     }
  838. }
  839.  
  840. //------------------------------------------------------------------------------
  841. // ODNameResolver::TokenIsDefault
  842. //------------------------------------------------------------------------------
  843. SOM_Scope ODBoolean  SOMLINK ODNameResolverTokenIsDefault(ODNameResolver *somSelf, Environment *ev,
  844.         AEDesc* token )
  845. {
  846.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  847.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverTokenIsDefault");
  848.  
  849.     WASSERT( token->descriptorType == typeUserToken );
  850.     return SIContextFromOSLToken(somSelf, token)->IsDefaultToken();
  851. }
  852.  
  853. //------------------------------------------------------------------------------
  854. // GetUserODToken
  855. //
  856. //    Get the "user" token from the token that the OSL passes around.
  857. //
  858. //    The userToken is the first four bytes.
  859. //------------------------------------------------------------------------------
  860.  
  861. ODDesc* GetUserODToken(OSLToken* oslToken)
  862. {
  863.     return *((ODDesc**)(*(oslToken->dataHandle)));
  864. }
  865.  
  866. //------------------------------------------------------------------------------
  867. // ODNameResolver::GetUserToken
  868. //
  869. //    Optimization: Don't have make OD token into AEDesc. We know the format of
  870. //    an OSLToken exactly. The ODDesc* will be in the first four bytes of the
  871. //    data.
  872. //------------------------------------------------------------------------------
  873.  
  874. SOM_Scope ODDesc*  SOMLINK ODNameResolverGetUserToken(ODNameResolver *somSelf, Environment *ev,
  875.         ODOSLToken* token)
  876. {
  877. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  878.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverGetUserToken");
  879.  
  880.     ODDesc*    retVal = kODNULL;
  881.  
  882.     SOM_TRY
  883.         AEDesc    tokenAsAEDesc;
  884.  
  885.         if ( token->GetDescType(ev) != typeUserToken)
  886.             THROW( kODErrNotAnODToken );
  887.  
  888.         THROW_IF_ERROR(ODDescToAEDesc(token, &tokenAsAEDesc));
  889.         retVal = GetUserODToken(&tokenAsAEDesc);
  890.         AEDisposeDesc(&tokenAsAEDesc);
  891. #if 0
  892.         AEDesc tokenAsAEDesc;
  893.         THROW_IF_ERROR( ODDescToAEDesc( token, &tokenAsAEDesc ) );
  894.         if ( tokenAsAEDesc.descriptorType != typeUserToken)
  895. //            THROW( kODErrInvalidParameter );
  896.     
  897.         if ( tokenAsAEDesc.dataHandle == kODNULL)
  898. //            THROW( kODErrInvalidParameter );
  899.     
  900.         AEDesc* userAEDesc = new AEDesc;
  901.         // EXTRACT USER TOKEN FROM DATAHANDLE.
  902.         *userAEDesc = *((AEDesc*)(*(tokenAsAEDesc.dataHandle)));
  903.         AEDesc    tempAEDesc;
  904.         AEDuplicateDesc(userAEDesc, &tempAEDesc);
  905.     
  906.         ODDesc* userToken = new ODDesc();
  907.         THROW_IF_NULL(userToken);
  908.         userToken->InitODDesc(ev);
  909.     
  910.         THROW_IF_ERROR( AEDescToODDesc(userAEDesc, userToken ) );
  911.         userToken->SetHadToAllocate(ev);
  912.     
  913.         *desc = userToken;
  914. #endif /* 0 */
  915.     SOM_CATCH_ALL
  916.     SOM_ENDTRY
  917.     
  918.     return retVal;
  919. }
  920.  
  921. //------------------------------------------------------------------------------
  922. // ODNameResolver::IsODToken
  923. //------------------------------------------------------------------------------
  924.  
  925. SOM_Scope ODBoolean  SOMLINK ODNameResolverIsODToken(ODNameResolver *somSelf, Environment *ev,
  926.         ODOSLToken* token)
  927. {
  928. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  929.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverIsODToken");
  930.     WASSERT( token );
  931.     return token->GetDescType(ev) == typeUserToken;
  932. }
  933.  
  934. //------------------------------------------------------------------------------
  935. // ODNameResolver::GetContextFromToken
  936. //------------------------------------------------------------------------------
  937.  
  938. SOM_Scope void  SOMLINK ODNameResolverGetContextFromToken(ODNameResolver *somSelf, Environment *ev,
  939.         ODOSLToken* token,
  940.         ODPart** part,
  941.         ODFrame** frame)
  942. {
  943. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  944.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverGetContextFromToken");
  945.     
  946.     WASSERT(part);
  947.     WASSERT(frame);
  948.  
  949.     SOM_TRY
  950.         AEDesc realToken;
  951.         THROW_IF_ERROR( ODDescToAEDesc( token, &realToken ) );
  952.     
  953.         WASSERT( realToken.descriptorType == typeUserToken );
  954.         *part = kODNULL;
  955.         *frame = kODNULL;
  956.         
  957.         // $$$$$This is really really really gross!  Why the hell can't we define
  958.         // a struct so we don't have to blindly grop around inside the handle?
  959.         //    I agree-NP-it will be done.
  960.     
  961.         OSLContext context = *(OSLContext*)
  962.                 ((*(realToken.dataHandle))+sizeof(ODDesc*));
  963.         (void)AEDisposeDesc( &realToken );
  964.         *part = PartFromContext(&context);
  965.         *frame = FrameFromContext(&context);
  966.         ASSERT_FRAME_MATCHES_PART( ev, *frame, *part );
  967.     SOM_CATCH_ALL
  968.     SOM_ENDTRY
  969. }
  970.  
  971. //------------------------------------------------------------------------------
  972. // ODNameResolver::CreateSwapToken
  973. //------------------------------------------------------------------------------
  974.  
  975. SOM_Scope void  SOMLINK ODNameResolverCreateSwapToken(ODNameResolver *somSelf, Environment *ev,
  976.         ODOSLToken* token,
  977.         ODPart* part,
  978.         ODFrame* frame)
  979. {
  980.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  981.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverCreateSwapToken");
  982.  
  983.     SOM_TRY
  984.  
  985. //    if (frame)
  986.     ASSERT_FRAME_MATCHES_PART( ev, frame, part );
  987.     
  988.     OSLToken localToken ;
  989.     THROW_IF_ERROR( ODDescToAEDesc( token, &localToken ) );
  990.  
  991.     OSLSetTokenDescType(&localToken, kSwitchDescType);
  992.  
  993.     OSLContext                context;
  994.  
  995.     somSelf->GetContextForPart(ev, part, frame, &context);
  996.     OSLSetTokenContext(&localToken, &context);
  997.  
  998.     THROW_IF_ERROR( AEDescToODDesc( &localToken, token ) );
  999.     (void)AEDisposeDesc( &localToken );
  1000.  
  1001.     SOM_CATCH_ALL
  1002.     SOM_ENDTRY
  1003. }
  1004.  
  1005. //------------------------------------------------------------------------------
  1006. // ODNameResolver::CallObjectAccessor
  1007. //------------------------------------------------------------------------------
  1008.  
  1009. SOM_Scope void  SOMLINK ODNameResolverCallObjectAccessor(ODNameResolver *somSelf, Environment *ev,
  1010.         ODPart* part,
  1011.         ODDescType desiredClass,
  1012.         ODOSLToken* containerToken,
  1013.         ODDescType containerClass,
  1014.         ODDescType keyForm,
  1015.         ODDesc* keyData,
  1016.         ODOSLToken* token)
  1017. {
  1018.     ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  1019.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverCallObjectAccessor");
  1020.  
  1021.     SOM_TRY
  1022.  
  1023.     OSLContext    curContext;
  1024.  
  1025.     // CHECK THAT CURRENT CONTEXT IS THE SAME AS CONTEXT FOR thePart
  1026.     if (part != somSelf->GetCurrentContextPart(ev))
  1027.         THROW(errAEAccessorNotFound);
  1028.  
  1029.     THROW_IF_ERROR(GetCurrentContext(&curContext));
  1030.  
  1031. //    Don't bother putting anything *in* realToken since it'll just get
  1032. //    overwritten later (by NewODToken)
  1033.     AEDesc realToken = NULL_DESCRIPTOR_DEFINITION;
  1034. #define FIX_ODNAMERESOLVERCALLOBJECTACCESSOR_LEAK 0
  1035. #if FIX_ODNAMERESOLVERCALLOBJECTACCESSOR_LEAK
  1036. //    THIS IS SILLY. WE NEED TO REDESIGN NewODToken SO IT'S SMARTER ABOUT THIS.
  1037.     somSelf->DisposeToken(ev, token);
  1038.     token = new ODOSLToken();
  1039.     token->InitODOSLToken(ev);
  1040. #endif
  1041.     AEDesc realContainer;
  1042.     THROW_IF_ERROR( ODDescToAEDesc( containerToken, &realContainer ) );
  1043.  
  1044.     AEDesc realData;
  1045.     THROW_IF_ERROR( ODDescToAEDesc( keyData, &realData ) );
  1046.  
  1047.     THROW_IF_ERROR(OSLCallObjectAccessor(desiredClass,
  1048.                                         &realContainer,
  1049.                                         containerClass,
  1050.                                         keyForm,
  1051.                                         &realData,
  1052.                                         &realToken));
  1053.     (void)AEDisposeDesc( &realContainer );
  1054.     (void)AEDisposeDesc( &realData );
  1055.  
  1056.     THROW_IF_ERROR( AEDescToODDesc(&realToken, token ) );
  1057.     (void)AEDisposeDesc( &realToken );
  1058.  
  1059.     THROW_IF_ERROR(SetCurrentContext(&curContext));
  1060.  
  1061.     SOM_CATCH_ALL
  1062.     SOM_ENDTRY
  1063. }
  1064.  
  1065. //------------------------------------------------------------------------------
  1066. // ODNameResolver::DisposeToken
  1067. //------------------------------------------------------------------------------
  1068.  
  1069. SOM_Scope void  SOMLINK ODNameResolverDisposeToken(ODNameResolver *somSelf, Environment *ev,
  1070.         ODOSLToken* theToken)
  1071. {
  1072. //    ODNameResolverData *somThis = ODNameResolverGetData(somSelf);
  1073.     ODNameResolverMethodDebug("ODNameResolver","ODNameResolverDisposeToken");
  1074.  
  1075.     SOM_TRY
  1076.         // don't assert this: it could be a list too
  1077. //        WASSERT(somSelf->IsODToken(ev, theToken));
  1078.     
  1079.         OSLToken localToken;
  1080.         THROW_IF_ERROR( ODDescToAEDesc( theToken, &localToken ) );
  1081.         // NEED TO DELETE THE OBJECT HERE BECAUSE ONLY localToken GETS PASSED
  1082.         //    BACK INTO OUR CODE FROM THE OSL.
  1083.         ODDeleteObject(theToken);
  1084.         THROW_IF_ERROR(OSLDisposeToken(&localToken));
  1085.     SOM_CATCH_ALL
  1086.     SOM_ENDTRY
  1087. }
  1088.  
  1089. //------------------------------------------------------------------------------
  1090. // ReturnCallbackFuncCaller
  1091. //------------------------------------------------------------------------------
  1092.  
  1093. CallbackCallerProc ReturnCallbackFuncCaller(OSLCallbackSelector whichCallback)
  1094. {
  1095.     CallbackCallerProc    result;
  1096.  
  1097.     switch(whichCallback)
  1098.     {
  1099.         case kObjectAccessor:
  1100.             result = (CallbackCallerProc)CallObjectAccessor;
  1101.             break;
  1102.         case kCallbackFlagsGetter:
  1103.             result = (CallbackCallerProc)GetAppDoesFlags;
  1104.             break;
  1105.         case kCountProc:
  1106.             result = (CallbackCallerProc)CallCountProc;
  1107.             break;
  1108.         case kCompareProc:
  1109.             result = (CallbackCallerProc)CallCompareProc;
  1110.             break;
  1111.         case kDisposeTokenProc:
  1112.             result = (CallbackCallerProc)CallDisposeTokenProc;
  1113.             break;
  1114.         case kGetMarkTokenProc:
  1115.             result = (CallbackCallerProc)CallGetMarkTokenProc;
  1116.             break;
  1117.         case kMarkProc:
  1118.             result = (CallbackCallerProc)CallMarkProc;
  1119.             break;
  1120.         case kAdjustMarksProc:
  1121.             result = (CallbackCallerProc)CallAdjustMarksProc;
  1122.             break;
  1123.         case kGetErrDescProc:
  1124.             result = (CallbackCallerProc)CallGetErrDescProc;
  1125.             break;
  1126.         default:
  1127.             ASSERTM(false, 0, "NamRslvr.ReturnCallbackFuncCaller: Reached default case in switch.");
  1128.             break;
  1129.     }
  1130.  
  1131.     return result;
  1132. }
  1133.  
  1134. //------------------------------------------------------------------------------
  1135. // GetSI
  1136. //
  1137. //    Given a context refCon, find the ODSemanticInterface object and the ODPart
  1138. //    object corresponding. If they can't be found, return kODFalse; return
  1139. //    kODTrue otherwise.
  1140. //------------------------------------------------------------------------------
  1141.  
  1142. static ODSemanticInterface* GetSI(long contextRefCon, ODPart** thePart)
  1143. {
  1144.     ODNameResolver*    nameResolver
  1145.             = ((SIContext*)contextRefCon)->GetNameResolver();
  1146.     
  1147.     *thePart = ((SIContext*)contextRefCon)->GetPart();
  1148.     return nameResolver->AcquireSemtIntf(somGetGlobalEnvironment(),*thePart);
  1149. }
  1150.  
  1151. //------------------------------------------------------------------------------
  1152. // CreateNewODOSLToken
  1153. //
  1154. //    This function shares a lot of code with NewODToken. Let's consolidate!
  1155. //    -NP 6/21/95
  1156. //
  1157. //    Create an "OpenDoc token", one with context information and an embedded
  1158. //    ODDesc* for a user token.
  1159. //------------------------------------------------------------------------------
  1160.  
  1161. SOM_Scope void  SOMLINK ODNameResolverCreateNewODOSLToken(ODNameResolver *somSelf, Environment *ev,
  1162.         AEDesc* odOSLToken,
  1163.         ODDesc* userToken,
  1164.         ODPart* part,
  1165.         ODFrame* frame)
  1166. {
  1167.     OSLContext    context;
  1168.  
  1169.     somSelf->GetContextForPart(ev, part, frame, &context);
  1170.     odOSLToken->descriptorType = typeUserToken;
  1171.     odOSLToken->dataHandle = (Handle)ODNewHandle(sizeof(ODDesc*)
  1172.                                 + sizeof(OSLContext));
  1173.     OSLSetTokenContext(odOSLToken, &context);
  1174.     SetUserODToken(odOSLToken, userToken);
  1175. }
  1176.  
  1177. //------------------------------------------------------------------------------
  1178. // NewODToken
  1179. //
  1180. //    Takes the already allocated newToken and openDocToken and sets up an OpenDoc
  1181. //    style token.
  1182. //    Places a null descriptor in openDocToken as the "user token"
  1183. //------------------------------------------------------------------------------
  1184.  
  1185. static void NewODToken( ODNameResolver* me, ODOSLToken* openDocToken,
  1186.                          ODPart* part, ODFrame* frame, OSLToken* newToken )
  1187. {
  1188.     Environment*    ev = somGetGlobalEnvironment();
  1189.     OSLContext        context;
  1190.  
  1191.     WASSERT(openDocToken);
  1192.  
  1193.     // CHECK TO SEE IF THIS IS A NULL TOKEN
  1194.     DescType dt = openDocToken->GetDescType(ev);
  1195. //    ODBoolean okToOverwrite = (dt == 'dead') || (dt == typeNull);
  1196.     ODBoolean okToOverwrite = (dt == typeNull);
  1197.  
  1198. //    if (dt != 'dead' && dt != typeNull && dt != typeAEList &&
  1199. //            dt != typeObjectBeingExamined)
  1200. //    This ASSERT is bogus as the token can be anyone's mark token
  1201. //    if (dt != typeNull && dt != typeAEList && dt != typeObjectBeingExamined)
  1202. //        WARN("Some unknown descriptor type in NewODToken.");
  1203.  
  1204.     // MUST SAVE OFF ORIGINAL OSLToken FOR CERTAIN TOKENS.
  1205.     AEDesc savedToken;
  1206.     if ( !okToOverwrite )
  1207.         // what's there now MATTERS; save it for wrapping
  1208.         savedToken = *newToken;
  1209.     else
  1210.         MakeNULLDesc(&savedToken);
  1211.  
  1212.     // INITIALIZE OSLToken TO THE RIGHT THING.
  1213.     newToken->descriptorType = typeUserToken;
  1214.     // $$$$$ THIS KNOWLEDGE OF HOW BIG THE STRUCTURE IS SHOULD BE ENCAPSULATED
  1215.     //    SOMEWHERE ELSE!!!!
  1216.     Handle h = (Handle)ODNewHandle(sizeof(ODDesc*) + sizeof(OSLContext));
  1217.     newToken->dataHandle = h;
  1218.     // GET AN OSLContext FOR THIS PART.
  1219.     me->GetContextForPart(ev, part, frame, &context);
  1220.     OSLSetTokenContext(newToken, &context);
  1221.  
  1222.     // CREATE USER TOKEN AND STICK IT IN THE OSLToken.
  1223.     ODDesc* tmpToken = new ODDesc();
  1224.     THROW_IF_NULL(tmpToken);
  1225.     tmpToken->InitODDesc(ev);
  1226.     THROW_IF_ERROR( AEDescToODDesc( &savedToken, tmpToken ) );
  1227.     SetUserODToken(newToken, tmpToken);
  1228.  
  1229.     // FINALLY INITIALIZE openDocToken AS WELL
  1230.     THROW_IF_ERROR( AEDescToODDesc(newToken, openDocToken ) );
  1231. }
  1232.  
  1233. //------------------------------------------------------------------------------
  1234. // CopyContextIntoToken
  1235. //
  1236. //    Move 2nd 8 bytes of dataHandle from one token to the other.
  1237. //    Should use OSLGetTokenContext and OSLSetTokenContext instead.
  1238. //------------------------------------------------------------------------------
  1239.  
  1240. static void CopyContextIntoToken(const OSLToken* sourceToken,
  1241.                                     OSLToken* destToken)
  1242. {
  1243.     OSLContext    context = GETBYTESOFHANDLE(sourceToken->dataHandle, OSLContext,
  1244.                                             sizeof(AEDesc));
  1245.  
  1246.     SETBYTESOFHANDLE(destToken->dataHandle, OSLContext, context,
  1247.                         sizeof(AEDesc));
  1248. }
  1249.  
  1250. //------------------------------------------------------------------------------
  1251. // TokenDefaultCanHandle
  1252. //------------------------------------------------------------------------------
  1253.  
  1254. static ODBoolean TokenDefaultCanHandle( Environment* ev,
  1255.         ODNameResolver* resolver, ODOSLToken* token )
  1256. {
  1257.     ODBoolean result = kODFalse;
  1258.     AEDesc realToken;
  1259.     THROW_IF_ERROR( ODDescToAEDesc( token, &realToken ) );
  1260.     switch ( realToken.descriptorType )
  1261.     {
  1262.         case typeUserToken:
  1263.             if ( !resolver->TokenIsDefault(ev, &realToken) )
  1264.             {
  1265.                 ODDesc* userToken;
  1266.                 userToken = resolver->GetUserToken( ev, token );
  1267.                 AEDesc realUserToken;
  1268.                 THROW_IF_ERROR( ODDescToAEDesc( userToken, &realUserToken ) );
  1269.  
  1270.                 ODBoolean isStandardToken =
  1271.                         CanBeStandardPartToken( &realUserToken )
  1272.                         || realUserToken.descriptorType == typeNull
  1273.                         || realUserToken.descriptorType == typeObjectBeingExamined;
  1274.  
  1275.                 AEDisposeDesc(&realUserToken);
  1276.  
  1277.                 result = isStandardToken;
  1278.             }
  1279.             else
  1280.                 result = kODTrue;
  1281.             break;
  1282.         case typeNull:
  1283.             result = kODTrue;
  1284.             break;
  1285.     }
  1286.     (void)AEDisposeDesc( &realToken );
  1287.     return result;
  1288. }
  1289.  
  1290. //------------------------------------------------------------------------------
  1291. // GetCallObjectAccessor
  1292. //
  1293. //    Used for compile-time type checking only.
  1294. //------------------------------------------------------------------------------
  1295.  
  1296. static ObjectAccessorCaller GetCallObjectAccessor()
  1297. {
  1298.     return CallObjectAccessor;
  1299. }
  1300.  
  1301. //------------------------------------------------------------------------------
  1302. // CallObjectAccessor
  1303. //------------------------------------------------------------------------------
  1304.  
  1305. static OSErr CallObjectAccessor(DescType        desiredClass,
  1306.                                     const OSLToken*    containerToken,
  1307.                                     DescType        containerClass,
  1308.                                     DescType        keyForm,
  1309.                                     const AEDesc*    keyData,
  1310.                                     OSLToken*        value,
  1311.                                     Boolean*        procFound,
  1312.                                     long            contextRefCon)
  1313. {
  1314.     OSErr                        error = noErr;
  1315.     TempODSemanticInterface        si = kODNULL;
  1316.     ODPart*                        thePart;
  1317.     Environment*                ev = somGetGlobalEnvironment();
  1318.     ODNameResolver*                nameResolver
  1319.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1320.     ODFrame* const                kNoFrameInfo = kODNULL;
  1321.     ODBoolean                    allocatedContainerToken = kODFalse;
  1322.     
  1323.     *procFound = false;
  1324.  
  1325.     TRY
  1326.         si = GetSI(contextRefCon, &thePart);
  1327.     
  1328.         ODDesc* dataODDesc = new ODDesc();
  1329.         THROW_IF_NULL(dataODDesc);
  1330.         dataODDesc->InitODDesc(ev);
  1331.         THROW_IF_ERROR( AEDescToODDesc( (AEDesc*)keyData, dataODDesc ));
  1332.     
  1333.         // INITIALIZE TOKENS (OPTIMIZATION?: SHOULD ONLY DO THIS IF WE CAN
  1334.         //    ACTUALLY CALL AN OBJECT ACCESSOR.)
  1335.     
  1336.         ODOSLToken* containerODDesc = new ODOSLToken();
  1337.         THROW_IF_NULL(containerODDesc);
  1338.         containerODDesc->InitODOSLToken(ev);
  1339.         THROW_IF_ERROR(AEDescToODDesc((OSLToken*)containerToken,
  1340.                                         containerODDesc));
  1341.     
  1342.         ODOSLToken* valueWrapper = new ODOSLToken();
  1343.         THROW_IF_NULL(valueWrapper);
  1344.         valueWrapper->InitODOSLToken(ev);
  1345.     
  1346.         OSLContext context;
  1347.         GetCurrentContext(&context);
  1348.         ODFrame* frame = FrameFromContext(&context);
  1349.         ASSERT_FRAME_MATCHES_PART( ev, frame, thePart );
  1350.     
  1351.         if (!nameResolver->IsODToken(ev, valueWrapper))
  1352.             NewODToken( nameResolver, valueWrapper, thePart, frame, value);
  1353.     
  1354.         //  HANDLE NULL CONTAINER TOKEN.
  1355.         if (!nameResolver->IsODToken(ev, containerODDesc))
  1356.         {
  1357.             NewODToken(nameResolver, containerODDesc, thePart,
  1358.                         frame,  (AEDesc*)containerToken);
  1359.             allocatedContainerToken = kODTrue;
  1360.         }
  1361.     
  1362.         if ( si )
  1363.         {
  1364.             TRY
  1365.                 si->CallObjectAccessor(ev, thePart, (ODDescType)desiredClass,
  1366.                                     containerODDesc,
  1367.                                     (ODDescType)containerClass,
  1368.                                     (ODDescType)keyForm, dataODDesc,
  1369.                                     valueWrapper);
  1370.                 SetIsDefaultToken(nameResolver, valueWrapper, kODFalse);
  1371.             CATCH_ALL
  1372.                 error = ErrorCode();
  1373.             ENDTRY
  1374.         }
  1375.     
  1376.         if ( (error == errAEEventNotHandled || !si)
  1377.                 && TokenDefaultCanHandle( ev, nameResolver, containerODDesc) )
  1378.         {
  1379.             ODMessageInterface* msgintf =
  1380.                     nameResolver->GetSession(ev)->GetMessageInterface(ev);
  1381.             DefaultAccessorSI* defaultSI =
  1382.                     (DefaultAccessorSI*)msgintf->GetDefaultSI(ev);
  1383.             
  1384.             TRY
  1385.                 defaultSI->CallObjectAccessor(ev, thePart, desiredClass,
  1386.                         containerODDesc, containerClass, keyForm,
  1387.                         dataODDesc, valueWrapper);
  1388.                 SetIsDefaultToken(nameResolver, valueWrapper, kODTrue);
  1389.                 error = kODNoError;
  1390.             CATCH_ALL
  1391.                 error = ErrorCode();
  1392.             ENDTRY
  1393.         }
  1394.  
  1395.         // <eeh> part of memory leak fixing though I no longer remember
  1396.         // quite what leak....
  1397.  
  1398.         if ( error == noErr )
  1399.             THROW_IF_ERROR( ODDescToAEDesc(valueWrapper, value) );
  1400.  
  1401.         ODDeleteObject(valueWrapper);
  1402.         ODDeleteObject(dataODDesc);
  1403.         if (allocatedContainerToken)
  1404.         {
  1405.             ODDesc*     userToken = nameResolver->GetUserToken(ev, containerODDesc);
  1406.             DescType dt = nameResolver->GetUserToken(ev, containerODDesc)
  1407.                                             ->GetDescType(ev);
  1408.  
  1409.             // $$$$$ SHOULDN'T USE NEWODTOKEN FOR CONTAINERS. IT ALLOCATES
  1410.             //    A AEDESC WHEN WE DON'T NEED IT. HERE WE CHECK TO SEE IF IT DID
  1411.             //    THIS AND GET RID OF IT IF SO. FIX THIS!!!!!
  1412. //            if ( (dt == 'dead') || (dt == typeNull)
  1413. //                    || (dt == typeObjectBeingExamined) )
  1414.             if ( (dt == typeNull) || (dt == typeObjectBeingExamined) )
  1415.                 AEDisposeDesc((AEDesc*)containerToken);
  1416.  
  1417.             nameResolver->DisposeToken(ev, containerODDesc);
  1418.         }
  1419. #define FIX_FOR_EVERY_LEAK 1
  1420. #if FIX_FOR_EVERY_LEAK
  1421.         else
  1422.             ODDeleteObject(containerODDesc);
  1423. #endif
  1424.     CATCH_ALL
  1425.         error = ErrorCode();
  1426.     ENDTRY
  1427.  
  1428.     return error;
  1429. }
  1430.  
  1431. //------------------------------------------------------------------------------
  1432. // GetGetAppDoesFlags
  1433. //
  1434. //    Used for compile-time type checking only.
  1435. //------------------------------------------------------------------------------
  1436.  
  1437. static CallbackFlagsGetter GetGetAppDoesFlags()
  1438. {
  1439.     return GetAppDoesFlags;
  1440. }
  1441.  
  1442. //------------------------------------------------------------------------------
  1443. // GetAppDoesFlags
  1444. //------------------------------------------------------------------------------
  1445.  
  1446. static long GetAppDoesFlags(long contextRefCon)
  1447. {
  1448.     ODPart*                    thePart;
  1449.     TempODSemanticInterface    si = GetSI(contextRefCon, &thePart);
  1450.     
  1451.     if( !si )
  1452.         return kAEIDoMinimum;
  1453.     else
  1454.     {
  1455.         Environment* ev = somGetGlobalEnvironment();
  1456.         long result = si->GetOSLSupportFlags(ev);
  1457.         return result;
  1458.     }
  1459. }
  1460.  
  1461. //------------------------------------------------------------------------------
  1462. // GetSpecialProc
  1463. //
  1464. //    Lookup special proc given a context. Return kODFalse if not found, kODTrue
  1465. //    otherwise.
  1466. //------------------------------------------------------------------------------
  1467. #if 0
  1468. static ODBoolean GetSpecialProc(long                            contextRefCon,
  1469.                                     ODSemanticInterface*&        si,
  1470.                                     ODPart*&                    thePart)
  1471. {
  1472.     si = GetSI(contextRefCon, &si, &thePart);
  1473.     if( !si )
  1474.         return kODFalse;
  1475.  
  1476. //    theSI->GetSpecialHandler(funcType, &proc, &refCon);
  1477.  
  1478. //    if (!proc)
  1479. //        return kODFalse;
  1480.     
  1481.     return kODTrue;
  1482. }
  1483. #endif
  1484. //------------------------------------------------------------------------------
  1485. // CallCountProcAux
  1486. //------------------------------------------------------------------------------
  1487.  
  1488. static void CallCountProcAux(DescType            desiredClass,
  1489.                                 DescType        containerClass,
  1490.                                 const OSLToken*    container,
  1491.                                 long*            result,
  1492.                                 long            contextRefCon,
  1493.                                 ODOSLToken*        containerWrapper)
  1494. {
  1495.     ODPart*                        thePart;
  1496.     Environment*                ev = somGetGlobalEnvironment();
  1497.     OSErr                        error = noErr;
  1498.     ODOSLToken*                    newContainerWrapper = kODNULL;
  1499.     ODNameResolver*                nameResolver
  1500.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1501.  
  1502.     {
  1503.         TempODSemanticInterface si = GetSI(contextRefCon, &thePart);
  1504.     
  1505.         // TRY WITH THE PART'S SI FIRST
  1506.         if (si)
  1507.         {
  1508.             TRY
  1509.                 si->CallCountProc(ev, thePart, desiredClass, containerClass,
  1510.                                         containerWrapper, (ODSLong*)result);
  1511.             CATCH_ALL
  1512.                 error = ErrorCode();
  1513.             ENDTRY
  1514.         } else
  1515.             error = errAEEventNotHandled;
  1516.     }
  1517.  
  1518.     // SOME ERROR OCCURRED. TRY DEFAULT SI
  1519.     if (error == errAEEventNotHandled
  1520.             && TokenDefaultCanHandle( ev, nameResolver, containerWrapper))
  1521.     {
  1522.         TRY
  1523.             ODMessageInterface* msgintf =
  1524.                     nameResolver->GetSession(ev)->GetMessageInterface(ev);
  1525.             DefaultAccessorSI* defaultSI =
  1526.                     (DefaultAccessorSI*)msgintf->GetDefaultSI(ev);
  1527.     
  1528.             defaultSI->CallCountProc(ev, thePart, desiredClass,
  1529.                                         containerClass, containerWrapper,
  1530.                                         (ODSLong*)result);
  1531.             error = noErr;
  1532.         CATCH_ALL
  1533.             error = ErrorCode();
  1534.         ENDTRY
  1535.         
  1536.         THROW_IF_ERROR( error );
  1537.     }
  1538. }
  1539.  
  1540. //------------------------------------------------------------------------------
  1541. // GetCallCountProc
  1542. //
  1543. //    Used for compile-time type checking only.
  1544. //------------------------------------------------------------------------------
  1545.  
  1546. static CountProcCaller GetCallCountProc()
  1547. {
  1548.     return CallCountProc;
  1549. }
  1550.  
  1551. //------------------------------------------------------------------------------
  1552. // CallCountProc
  1553. //------------------------------------------------------------------------------
  1554.  
  1555. static OSErr CallCountProc(DescType            desiredClass,
  1556.                                 DescType        containerClass,
  1557.                                 const OSLToken*    container,
  1558.                                 long*            result,
  1559.                                 long            contextRefCon)
  1560. {
  1561.     Environment*                ev = somGetGlobalEnvironment();
  1562.     OSErr                        error = noErr;
  1563.     ODOSLToken*                    newContainerWrapper = kODNULL;
  1564.     ODDesc*                        userToken = kODNULL;
  1565.     AEDesc                        userTokenAsAEDesc;
  1566.     OSLContext                    savedCurContext;
  1567.     OSLContext                    newContext;
  1568.     ODFrame*                    theFrame;
  1569.     ODNameResolver*                nameResolver
  1570.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1571.     ODBoolean                    allocatedContainerToken = kODFalse;
  1572.  
  1573.     TRY
  1574.         // SET UP ODDESC FOR CONTAINER
  1575.         ODOSLToken* containerWrapper = new ODOSLToken();
  1576.         THROW_IF_NULL(containerWrapper);
  1577.         containerWrapper->InitODOSLToken(ev);
  1578.         THROW_IF_ERROR(AEDescToODDesc((AEDesc*)container, containerWrapper));
  1579.  
  1580.         // INITIALIZE CONTAINER TOKEN TO OPENDOC TOKEN
  1581.         //    GET USER TOKEN SO THAT WE CAN LOOK AT IT
  1582.         //    WE ASSUME HERE THAT ONLY TIME THIS CAN HAPPEN IN WHEN THE SHELL IS
  1583.         //    INVOLVED.
  1584.         if (!nameResolver->IsODToken(ev, containerWrapper))
  1585.         {
  1586.             NewODToken(nameResolver, containerWrapper, kODAppShell, kODNULL,
  1587.                         (OSLToken*)container);
  1588.             allocatedContainerToken = kODTrue;
  1589.             MakeNULLToken(&userTokenAsAEDesc); // container?
  1590.         }
  1591.         else
  1592.         {
  1593.             userToken = nameResolver->GetUserToken(ev, containerWrapper);
  1594.             THROW_IF_ERROR(ODDescToAEDesc(userToken, &userTokenAsAEDesc));
  1595.         }
  1596.  
  1597.         TRY
  1598.             CallCountProcAux(desiredClass, containerClass, container, result,
  1599.                                 contextRefCon, containerWrapper);
  1600.         CATCH_ALL
  1601.             error = ErrorCode();
  1602.         ENDTRY
  1603.  
  1604.         // TRY SWAPPING TO EMBEDDED FRAME IF THE PART RETURNS THE SPECIAL
  1605.         //    "SWAP" RESULT.
  1606.  
  1607.         // NORMALLY, WE SHOULD ONLY ALLOW SWAPPING IF THE CONTAINER IS A
  1608.         //    STANDARD PART TOKEN. HOWEVER, WHEN thePart IS kODNULL, THEN WE
  1609.         //    KNOW THAT THE APPLICATION IS THE CONTAINER AND THE REQUEST TO
  1610.         //    SWAP SHOULD BE TRANSLATED INTO A SWAP TO THE ROOT PART.
  1611.         
  1612.         // IS THERE ANOTHER CASE WE HAVE TO WORRY ABOUT?
  1613.         
  1614.         if (*result == kODCountProcSwapValue && error == noErr)
  1615.         {
  1616.             ODPart* thePart = kODNULL;
  1617.             if ( CanBeStandardPartToken( &userTokenAsAEDesc ) )
  1618.             {
  1619.                 PartFrameFromStandardPartToken( &userTokenAsAEDesc, &thePart,
  1620.                         &theFrame );
  1621.                 thePart->Acquire(ev);
  1622.             }
  1623.             else
  1624.             {
  1625.                 theFrame = GetDefaultRootFrameToSwapTo(ev,
  1626.                                             nameResolver->GetSession(ev));
  1627.                 thePart = theFrame->AcquirePart(ev);
  1628.             }
  1629.             
  1630.             { TempODPart tempPart = thePart; // ensure it's released
  1631.  
  1632.               THROW_IF_ERROR(GetCurrentContext(&savedCurContext));
  1633.             
  1634.               nameResolver->GetContextForPart(ev, thePart, theFrame,
  1635.                                             &newContext);
  1636.             }
  1637.             
  1638.             THROW_IF_ERROR(SetCurrentContext(&newContext));
  1639.             
  1640.             TRY
  1641.                 // SET UP A NULL CONTAINER.
  1642.  
  1643.                 // SET THE USER TOKEN TO NULL AND SET THE CONTEXT OF THE
  1644.                 //    TOKEN TO THE RIGHT THING.
  1645.  
  1646.                 ODDesc*    tempODDesc = new ODDesc();
  1647.                 THROW_IF_NULL(tempODDesc);
  1648.                 tempODDesc->InitODDesc(ev);
  1649.  
  1650. #define FIX_FOR_WHOSE_LEAK 1
  1651. #if FIX_FOR_WHOSE_LEAK
  1652.                 // SAVE OLD CONTAINER ODOSLTOKEN
  1653.                 ODOSLToken*    oldContainerWrapper = containerWrapper;
  1654.  
  1655.                 containerWrapper = new ODOSLToken();
  1656.                 THROW_IF_NULL(containerWrapper);
  1657.                 containerWrapper->InitODOSLToken(ev);
  1658. #endif
  1659.  
  1660.                 SetUserODToken((OSLToken*)container, tempODDesc);
  1661.                 OSLSetTokenContext((OSLToken*)container, &newContext);
  1662.                 THROW_IF_ERROR( AEDescToODDesc( (AEDesc*)container, containerWrapper ) );
  1663.  
  1664.                 // RESET CONTAINER CLASS
  1665.                 containerClass = typeNull;
  1666.  
  1667.                 TRY
  1668.                     CallCountProcAux(desiredClass, containerClass, container,
  1669.                                     result, newContext.refCon,
  1670.                                     containerWrapper);
  1671.                 CATCH_ALL
  1672.                     error = ErrorCode();
  1673.                 ENDTRY
  1674.                 // RESTORE PREVIOUS USER TOKEN.  Restore even in case
  1675.                 // of error so dispose will Release Frame and Part (for
  1676.                 // the common case where we tried swapping to a StdPartToken.
  1677.                 
  1678. #if FIX_FOR_WHOSE_LEAK
  1679.                 nameResolver->DisposeToken(ev, containerWrapper);
  1680.                 containerWrapper = oldContainerWrapper;
  1681. #endif
  1682.                 
  1683.                 SetUserODToken((OSLToken*)container, userToken);
  1684.                 THROW_IF_ERROR(error);
  1685.                 if ( *result == kODCountProcSwapValue )
  1686.                     THROW( errAEEventNotHandled );
  1687.             CATCH_ALL
  1688.                 THROW_IF_ERROR(SetCurrentContext(&savedCurContext));
  1689.                 RERAISE;
  1690.             ENDTRY
  1691.             
  1692.             THROW_IF_ERROR(SetCurrentContext(&savedCurContext));
  1693.         }
  1694.  
  1695.         if (allocatedContainerToken)
  1696.             nameResolver->DisposeToken(ev, containerWrapper);
  1697.     CATCH_ALL
  1698.         error = ErrorCode();
  1699.     ENDTRY
  1700.  
  1701.     (void)AEDisposeDesc( &userTokenAsAEDesc );
  1702.     return error;
  1703. }
  1704.  
  1705. //------------------------------------------------------------------------------
  1706. // GetCallCompareProc
  1707. //
  1708. //    Used for compile-time type checking only.
  1709. //------------------------------------------------------------------------------
  1710.  
  1711. static CompareProcCaller GetCallCompareProc()
  1712. {
  1713.     return CallCompareProc;
  1714. }
  1715.  
  1716. //------------------------------------------------------------------------------
  1717. // CallCompareProc
  1718. //------------------------------------------------------------------------------
  1719.  
  1720. static ODOSLToken* MakeODOSLToken( Environment* ev, ODNameResolver* nameResolver,
  1721.         ODPart* part, ODFrame* frame, const AEDesc* desc );
  1722. static ODOSLToken* MakeODOSLToken( Environment* ev, ODNameResolver* nameResolver,
  1723.         ODPart* part, ODFrame* frame, const AEDesc* desc )
  1724. {
  1725.     ODOSLToken* result = new ODOSLToken();
  1726.     THROW_IF_NULL(result);
  1727.     result->InitODOSLToken(ev);
  1728.  
  1729.     if ( noErr == AEDescToODDesc( (OSLToken*)desc, result ) )
  1730.     {
  1731.         return result;
  1732.     }
  1733.     else
  1734.     {
  1735.         ODDeleteObject(result);
  1736.         return kODNULL;
  1737.     }
  1738. }
  1739.  
  1740. static OSErr CallCompareProc(DescType            oper,
  1741.                                 const OSLToken*    obj1,
  1742.                                 const OSLToken*    obj2,
  1743.                                 ODBoolean*        result,
  1744.                                 long            contextRefCon)
  1745. {
  1746.     OSErr                        error = noErr;
  1747.     TempODSemanticInterface        si = kODNULL;
  1748.     Environment*                ev = somGetGlobalEnvironment();
  1749.     ODPart*                        thePart;
  1750.     ODOSLToken* tokenWrapper1 = kODNULL;    ODVolatile(tokenWrapper1);
  1751.     ODOSLToken* tokenWrapper2 = kODNULL;    ODVolatile(tokenWrapper2);
  1752.     ODNameResolver*                nameResolver
  1753.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1754.  
  1755.     TRY
  1756.         si = GetSI( contextRefCon, &thePart );
  1757.         ODFrame* frame = ((SIContext*)contextRefCon)->GetFrame();
  1758.         tokenWrapper1 = MakeODOSLToken( ev, nameResolver, thePart, frame, obj1 );
  1759.         tokenWrapper2 = MakeODOSLToken( ev, nameResolver, thePart, frame, obj2 );
  1760.     CATCH_ALL
  1761.         error = ErrorCode();
  1762.     ENDTRY
  1763.  
  1764.     if ( !error )
  1765.     {
  1766.         if ( si )
  1767.         {
  1768.             TRY
  1769.                 si->CallCompareProc( ev, thePart, oper, tokenWrapper1,
  1770.                                         tokenWrapper2, result );
  1771.             CATCH_ALL
  1772.                 error = ErrorCode();
  1773.             ENDTRY
  1774.         }
  1775.         
  1776.         // don't touch the error code already returned.  Return it if the
  1777.         // defaults fail.
  1778.         if ( !si || error == errAEEventNotHandled )
  1779.                     // <eeh> what value means failed to compare?
  1780.         {
  1781.             TRY
  1782.                 ODMessageInterface* msgintf =
  1783.                         nameResolver->GetSession(ev)->GetMessageInterface(ev);
  1784.                 DefaultAccessorSI* defaultSI =
  1785.                         (DefaultAccessorSI*)msgintf->GetDefaultSI(ev);
  1786.                 defaultSI->CallCompareProc( ev, thePart, oper, tokenWrapper1,
  1787.                                         tokenWrapper2, result );
  1788.                 // If we got here, there was no error.
  1789.                 error = noErr;
  1790.             CATCH_ALL
  1791.                 error = ErrorCode();
  1792.             ENDTRY
  1793.         }
  1794.     }
  1795.  
  1796.     ODDeleteObject(tokenWrapper1);
  1797.     ODDeleteObject(tokenWrapper2);
  1798.     return error;
  1799. }
  1800.  
  1801. //------------------------------------------------------------------------------
  1802. // GetCallDisposeTokenProc
  1803. //
  1804. //    Used for compile-time type checking only.
  1805. //------------------------------------------------------------------------------
  1806.  
  1807. static DisposeTokenProcCaller GetCallDisposeTokenProc()
  1808. {
  1809.     return CallDisposeTokenProc;
  1810. }
  1811.  
  1812. //------------------------------------------------------------------------------
  1813. // CallDisposeTokenProc
  1814. //------------------------------------------------------------------------------
  1815.  
  1816. static OSErr CallDisposeTokenProc(OSLToken*    unneededToken,
  1817.                                     long        contextRefCon)
  1818. {
  1819.     TempODSemanticInterface        si = kODNULL;
  1820.     ODPart*                        thePart;
  1821.     Environment*                ev = somGetGlobalEnvironment();
  1822.     OSErr                        error = noErr;
  1823.     ODNameResolver*                nameResolver
  1824.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1825.     ODOSLToken*                    tokenWrapper = kODNULL;        ODVolatile(tokenWrapper);
  1826.  
  1827.     TRY
  1828.         TRY
  1829.             si = GetSI( contextRefCon, &thePart );
  1830.             tokenWrapper = new ODOSLToken();
  1831.             THROW_IF_NULL(tokenWrapper);
  1832.             tokenWrapper->InitODOSLToken(ev);
  1833.             THROW_IF_ERROR( AEDescToODDesc( unneededToken, tokenWrapper ) );
  1834.         CATCH_ALL
  1835.             error = ErrorCode();
  1836.         ENDTRY
  1837.     
  1838.         if ( !error )
  1839.         {
  1840.             ODDesc*    userToken = kODNULL;
  1841.  
  1842.             // GET A REFERENCE TO THE USER TOKEN (IF ANY) HERE, SO THAT WE STILL
  1843.             //    HAVE A VALID REFERENCE TO IT IF THE USER'S DISPOSETOKEN PROC
  1844.             //    DEALLOCATES THE ODOSLToken.
  1845.             if (nameResolver->IsODToken(ev, tokenWrapper)
  1846.                     || (unneededToken->descriptorType == kSwitchDescType))
  1847.                 userToken = GetUserODToken(unneededToken);
  1848.  
  1849.             TRY
  1850.                 if ( si )
  1851.                     si->CallDisposeTokenProc(ev, thePart, tokenWrapper);
  1852.             CATCH_ALL
  1853.                 error = ErrorCode();
  1854.             ENDTRY
  1855.         
  1856.             if ( !si || (error == errAEEventNotHandled) )
  1857.             {
  1858.                 TRY
  1859.                     ODMessageInterface* msgintf =
  1860.                             nameResolver->GetSession(ev)->GetMessageInterface(ev);
  1861.                     DefaultAccessorSI* defaultSI =
  1862.                             (DefaultAccessorSI*)msgintf->GetDefaultSI(ev);
  1863.                     defaultSI->CallDisposeTokenProc(ev, thePart, tokenWrapper);
  1864.                 CATCH_ALL
  1865.                     error = ErrorCode();
  1866.                 ENDTRY
  1867.             }
  1868.     
  1869.             // ALWAYS DELETE THE USER TOKEN
  1870.             if (userToken)
  1871.                 delete userToken;
  1872.             
  1873.             // ONLY DELETE THE TOKEN ITSELF IF NO ONE ELSE HANDLED IT.
  1874.             if (error)
  1875.             {
  1876.     //            WARN("No dispose token proc handled it. NameResolver handling.");
  1877.                 ODDeleteObject(tokenWrapper);
  1878.             }
  1879.         }
  1880.     CATCH_ALL
  1881.         error = ErrorCode();
  1882.     ENDTRY
  1883.  
  1884.     // IF THERE WAS NO ERROR, MAKE SURE WE DISPOSE THE AEDESC, BUT THE OSL
  1885.     //    WON'T. IT WILL IF WE RETURN AN ERROR.
  1886.     if (error == kODNoError)
  1887.         AEDisposeDesc(unneededToken);
  1888.  
  1889.     return error;
  1890. }
  1891.  
  1892. //------------------------------------------------------------------------------
  1893. // GetMarkProc
  1894. //
  1895. //    Used for compile-time type checking only.
  1896. //------------------------------------------------------------------------------
  1897.  
  1898. static MarkProcCaller GetMarkProc()
  1899. {
  1900.     return CallMarkProc;
  1901. }
  1902.  
  1903. //------------------------------------------------------------------------------
  1904. // CallMarkProc
  1905. //------------------------------------------------------------------------------
  1906.  
  1907. static OSErr CallMarkProc(const OSLToken*    dToken,
  1908.                             const OSLToken*    markToken,
  1909.                             long            index,
  1910.                             long            contextRefCon)
  1911. {
  1912.     OSErr                        error = noErr;
  1913.     Environment*                ev = somGetGlobalEnvironment();
  1914.     ODPart*                        thePart;
  1915.     ODNameResolver*                nameResolver
  1916.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1917.  
  1918.     TempODSemanticInterface si = GetSI(contextRefCon, &thePart);
  1919.     if( !si )
  1920.         return errAENotASpecialFunction;
  1921.  
  1922.     ODOSLToken* tokenWrapper = kODNULL;            ODVolatile(tokenWrapper);
  1923.     ODOSLToken* markTokenWrapper = kODNULL;        ODVolatile(markTokenWrapper);
  1924.     TRY
  1925.         tokenWrapper = new ODOSLToken();
  1926.         THROW_IF_NULL(tokenWrapper);
  1927.         tokenWrapper->InitODOSLToken(ev);
  1928.         THROW_IF_ERROR( AEDescToODDesc( (OSLToken*)dToken, tokenWrapper ) );
  1929.  
  1930.         markTokenWrapper = new ODOSLToken();
  1931.         THROW_IF_NULL(markTokenWrapper);
  1932.         markTokenWrapper->InitODOSLToken(ev);
  1933.         THROW_IF_ERROR(AEDescToODDesc( (OSLToken*)markToken, markTokenWrapper));
  1934.         si->CallMarkProc(ev, thePart, tokenWrapper,
  1935.                                 markTokenWrapper, index);
  1936.     CATCH_ALL
  1937.         error = ErrorCode();
  1938.     ENDTRY
  1939.     
  1940.     ODDeleteObject(tokenWrapper);
  1941.     ODDeleteObject(markTokenWrapper);
  1942.     return error;
  1943. }
  1944.  
  1945. //------------------------------------------------------------------------------
  1946. // GetMarkTokenProc
  1947. //
  1948. //    Used for compile-time type checking only.
  1949. //------------------------------------------------------------------------------
  1950.  
  1951. static GetMarkTokenProcCaller GetMarkTokenProc()
  1952. {
  1953.     return CallGetMarkTokenProc;
  1954. }
  1955.  
  1956. //------------------------------------------------------------------------------
  1957. // CallGetMarkTokenProc
  1958. //------------------------------------------------------------------------------
  1959.  
  1960. static OSErr CallGetMarkTokenProc(const OSLToken*    dContainerToken,
  1961.                                     DescType        containerClass,
  1962.                                     OSLToken*        result,
  1963.                                     long            contextRefCon)
  1964. {
  1965.     OSErr                    error = noErr;
  1966.     Environment*                ev = somGetGlobalEnvironment();
  1967.     ODPart*                thePart;
  1968.     ODNameResolver*                nameResolver
  1969.         = ((SIContext*)contextRefCon)->GetNameResolver();
  1970.  
  1971.     TempODSemanticInterface si = GetSI(contextRefCon, &thePart);
  1972.     if( !si )
  1973.         return errAENotASpecialFunction;
  1974.  
  1975.     ODOSLToken* tokenWrapper = kODNULL;        ODVolatile(tokenWrapper);
  1976.     TRY
  1977.         tokenWrapper = new ODOSLToken();
  1978.         THROW_IF_NULL(tokenWrapper);
  1979.         tokenWrapper->InitODOSLToken(ev);
  1980.         THROW_IF_ERROR( AEDescToODDesc( (OSLToken*)dContainerToken, tokenWrapper ) );
  1981.  
  1982.         ODOSLToken* resultWrapper = new ODOSLToken();
  1983.         THROW_IF_NULL(resultWrapper);
  1984.         resultWrapper->InitODOSLToken(ev);
  1985.         si->CallGetMarkTokenProc(ev, thePart, tokenWrapper,
  1986.                                                 containerClass,
  1987.                                                 resultWrapper);
  1988.         THROW_IF_ERROR( ODDescToAEDesc(resultWrapper, result));
  1989.         ODDeleteObject(resultWrapper);
  1990.     CATCH_ALL
  1991.         error = ErrorCode();
  1992.     ENDTRY
  1993.     
  1994.     ODDeleteObject(tokenWrapper);
  1995.     return error;
  1996. }
  1997.  
  1998. //------------------------------------------------------------------------------
  1999. // GetAdjustMarksProc
  2000. //
  2001. //    Used for compile-time type checking only.
  2002. //------------------------------------------------------------------------------
  2003.  
  2004. static AdjustMarksProcCaller GetAdjustMarksProc()
  2005. {
  2006.     return CallAdjustMarksProc;
  2007. }
  2008.  
  2009. //------------------------------------------------------------------------------
  2010. // CallAdjustMarksProc
  2011. //------------------------------------------------------------------------------
  2012.  
  2013. static OSErr CallAdjustMarksProc(long                newStart,
  2014.                                     long            newStop,
  2015.                                     const OSLToken*    markToken,
  2016.                                     long            contextRefCon)
  2017. {
  2018.     OSErr                    error = noErr;
  2019.     Environment*                ev = somGetGlobalEnvironment();
  2020.     ODPart*                thePart;
  2021.  
  2022.     TempODSemanticInterface si = GetSI(contextRefCon, &thePart);
  2023.     if (!si)
  2024.         return errAENotASpecialFunction;
  2025.  
  2026.     ODOSLToken* tokenWrapper = kODNULL;        ODVolatile(tokenWrapper);
  2027.     TRY
  2028.         tokenWrapper = new ODOSLToken();
  2029.         THROW_IF_NULL(tokenWrapper);
  2030.         tokenWrapper->InitODOSLToken(ev);
  2031.         THROW_IF_ERROR( AEDescToODDesc( (OSLToken*)markToken, tokenWrapper ) );
  2032.  
  2033.         si->CallAdjustMarksProc(ev, thePart, newStart, newStop,
  2034.                                                     tokenWrapper);
  2035.     CATCH_ALL
  2036.         error = ErrorCode();
  2037.     ENDTRY
  2038.     
  2039.     ODDeleteObject(tokenWrapper);
  2040.     return error;
  2041. }
  2042.  
  2043. //------------------------------------------------------------------------------
  2044. // GetGetErrDescProc
  2045. //
  2046. //    Used for compile-time type checking only.
  2047. //------------------------------------------------------------------------------
  2048.  
  2049. static GetErrDescProcCaller GetGetErrDescProc()
  2050. {
  2051.     return CallGetErrDescProc;
  2052. }
  2053.  
  2054. //------------------------------------------------------------------------------
  2055. // CallGetErrDescProc
  2056. //------------------------------------------------------------------------------
  2057.  
  2058. static OSErr CallGetErrDescProc(AEDesc**    appDescPtr,
  2059.                                     long    contextRefCon)
  2060. {
  2061.     TempODSemanticInterface        si = kODNULL;
  2062.     ODPart*                        thePart;
  2063.     Environment*                ev = somGetGlobalEnvironment();
  2064.     OSErr                        error = noErr;
  2065.     ODNameResolver*                nameResolver
  2066.         = ((SIContext*)contextRefCon)->GetNameResolver();
  2067.  
  2068.     si = GetSI(contextRefCon, &thePart);
  2069.     if (!si)
  2070.         return errAENotASpecialFunction;
  2071.  
  2072.     TRY
  2073.         ODDesc*    errorODDesc;
  2074.         si->CallGetErrDescProc(ev, thePart, &errorODDesc);
  2075.         *appDescPtr = nameResolver->AddErrDescToList(ev, errorODDesc);
  2076.     CATCH_ALL
  2077.         error = ErrorCode();
  2078.     ENDTRY
  2079.     return error;
  2080. }
  2081.  
  2082.